import type { GreasyForkElements } from '../../../../../../../../types/constants/personalization/greasy_fork'
import type { IUserData } from '../module/script_processor/types'
import { ThemeVarService } from '../../../../../../../../lib/abstract/style/theme_var/service'
import { ICON_IDS } from '../../../../../../../../lib/icons/types/constants'
import { PageHandler } from '../../../../../../../../lib/page_handler'
import { ToolKit } from '../../../../../../../../lib/utils/toolkit'
import { GreasyForkFeedbackMark } from '../../../../../../../../module/page_enhancer/interaction/platform/greasy_fork/feedback_mark'
import {
  AppStyleCollections,
  BodyClasses,
  getCurrentURL,
  PAGE_ELEMENTS,
  PROJECT_PREFIX,
  SUPPORTED_PLATFORMS,
} from '../../../../../../../../types/constants'
import { StylesService } from '../../../../../../../../types/constants/styles'
import { TOOLBAR_THEME_STYLE } from '../../../common'
import { CommonPage } from './common'

export class DiscussionsPage {
  elements: GreasyForkElements = PAGE_ELEMENTS[SUPPORTED_PLATFORMS.GREASY_FORK]
  private static instance: DiscussionsPage
  private pageHandler: PageHandler = PageHandler.getInstance()
  private commonPage: CommonPage = CommonPage.getInstance()
  protected readonly themeVarService: ThemeVarService = ThemeVarService.getInstance()
  private readonly stylesService: StylesService = StylesService.getInstance()

  private readonly selector: string = '.discussion-list .discussion-list-container'
  private readonly READ_CLASS = 'discussion-read'
  private readonly UNREAD_CLASS = 'discussion-not-read'

  /**
   * 获取单例实例
   */
  public static getInstance(): DiscussionsPage {
    if (!DiscussionsPage.instance) {
      DiscussionsPage.instance = new DiscussionsPage()
    }
    return DiscussionsPage.instance
  }

  init(): void {
    $(this.selector).each((index, element) => {
      const $element = $(element)
      const $userLink = $element.find('.discussion-meta > .discussion-meta-item > .user-link')
      const userId = this.pageHandler.services.greasyFork.getUserId($userLink)
      const userTypes = this.pageHandler.storages.greasyFork.getUserType(userId)

      // 隐藏用户链接
      $userLink.addClass(AppStyleCollections.Hide.ELEMENT)

      // 添加序号
      this.pageHandler.pages.base.addIndex(index, $element)

      // 添加用户头像
      const data: IUserData = {
        author: $userLink.text().trim(),
        authorUrl: $userLink.attr('href') || '',
      }
      this.pageHandler.features.user.addAvatar($element, data)

      // 添加用户类型徽章（！！！在用户头像后面）
      const $avatarContainer = $element.find(`.${AppStyleCollections.Body.AVATAR_CONTAINER}`)
      if (userTypes.length > 0 && $avatarContainer.length) {
        this.pageHandler.features.user.addUserTypeBadge($avatarContainer, userTypes)
      }

      // 初始化已读状态
      this.updateReadBadge($element, this.checkReadStatus($element))

      // 添加反馈徽章（不存在脚本链接时以及非 GreasyFork 论坛页面）
      const $scriptLink = $element.find('.discussion-meta-item-script-name .script-link')
      if (!$scriptLink || !$scriptLink.length) {
        if (!window.location.pathname.includes('greasyfork')) {
          this.addFeedbackBadge($element.find(`#${BodyClasses.INDEX_CONTAINER}`))
        }
        // 隐藏平台反馈提示
        $element.find('.discussion-meta-item-script-name').addClass(AppStyleCollections.Hide.ELEMENT)
      }
    })

    // 添加点击事件委托
    $(`${this.selector} .discussion-title`).on('click', (e) => {
      const $target = $(e.currentTarget)
      const $container = $target.closest(this.selector)

      this.markAsRead($container)
    })

    // 移除评分描述
    $(`.discussion-title .rating-icon`).text('')

    // 标识注销用户
    this.pageHandler.services.greasyFork.formatDeletedUser(`.discussion-meta > .discussion-meta-item > i`)
  }

  /**
   * 标记为已读
   */
  private markAsRead($container: JQuery): void {
    // 更新 UI 状态
    $container.addClass(this.READ_CLASS).removeClass(this.UNREAD_CLASS)

    // 更新徽章
    this.updateReadBadge($container, true)
  }

  /**
   * 更新已读徽章
   */
  private updateReadBadge($container: JQuery, isRead: boolean): void {
    const $badgeContainer = $container.find(`#${BodyClasses.INDEX_CONTAINER}`)
    const $readBadge = $badgeContainer.find('.read-badge')

    if (isRead) {
      if ($readBadge.length)
        return

      this.pageHandler.features.badge.addBadge($badgeContainer, 'read', '已读')
    }
    else {
      $readBadge.remove()
    }
  }

  /**
   * 检查并更新已读状态
   */
  private checkReadStatus($container: JQuery): boolean {
    return $container.hasClass(this.READ_CLASS)
  }

  /**
   * 添加反馈徽章
   */
  addFeedbackBadge($element: JQuery): void {
    const $badge = this.pageHandler.features.badge.addBadge($element, 'feedback', '平台反馈', { backgroundColor: 'linear-gradient(135deg, #FF9800, #FFC107)' })

    // 添加点击事件
    $badge.on('click', (_e) => {
      const baseUrl = getCurrentURL().replace(/\/+$/, '')
      const GreasyForkDiscussionUrl = `${baseUrl}/greasyfork`
      ToolKit.browser.url.openNewTab(GreasyForkDiscussionUrl)
    })
  }

  getMainStyles(): string {
    return `
.sidebarred {
  padding-top: 0 !important;
  background-color: var(--${PROJECT_PREFIX}-theme-bg-base) !important;
}

.sidebarred-main-content:has(> .discussion-list){
  .discussion-list-header {
    h2 {
      color: var(--${PROJECT_PREFIX}-theme-text-primary) !important;
      margin-left: 16px !important;
    }
  }
}

.sidebarred-main-content {
  p {
    color: var(--${PROJECT_PREFIX}-theme-text-secondary) !important;
  }
  
  .discussion-list-header {
    display: flex !important;
    flex-direction: row !important;
    align-items: center !important;
    width: 100% !important;

    h2 {
      color: var(--${PROJECT_PREFIX}-theme-text-primary) !important;
    }
    
    .discussion-actions {
      margin-left: auto !important;
      margin-right: 16px !important;

      a {
        ${this.stylesService.link.default()}
      }
    }
  }

  .discussion-list {
    background-color: transparent !important;
    box-shadow: none !important;
    border: none !important;
    
    /* 结果列表 */
    .discussion-list-container {
      grid-template-columns: auto 1fr;
      grid-template-rows: auto auto; /* 行数 */
      grid-template-areas:
        "index index"
        "avatar article";
      ${this.commonPage.baseListStyles()}
      
      /* 阅读状态 */
      &.discussion-read, &.discussion-not-read {
        background-color: transparent !important;
      }
      
      /* 内容区域 */
      .discussion-list-item {
        grid-area: article;
        min-width: 0; /* 防止内容溢出 */
        border: none !important;
      }
    }

    /* 标签 */
    ${GreasyForkFeedbackMark.getTagStyles()}
    
    /* 讨论列表 */
    .discussion-list-item {
      /* 工具栏 */
      ${TOOLBAR_THEME_STYLE}
      
      /* 用户链接 */
      .script-link, .user-link {
        ${this.stylesService.link.default()}
      }
      
      /* 脚本链接 */
      .script-link {
        align-items: center !important;
        max-width: 150px;

        &::before {
          ${this.stylesService.inlinePseudo.icon({ display: 'inline-block', backgroundImageId: ICON_IDS.link.link })}
        }
      }
      
      /* 元数据 */
      .discussion-meta {
        display: flex !important;
        align-items: center !important;
        
        .discussion-meta-item  {
          color: var(--${PROJECT_PREFIX}-theme-text-secondary) !important;
          
          &:has(.script-link) {
            flex: none !important;
          }
          
          /* 时间 */
          relative-time {
            color: var(--${PROJECT_PREFIX}-theme-text-secondary) !important;
          }
          
          /* 精确时间 */
          .gf-time-helper {
            white-space: nowrap !important;
          }
          
          .discussion-meta-item {
            display: flex !important;
            align-items: center !important;
            justify-content: flex-end !important;
            gap: 5px !important;
            white-space: nowrap !important;
            
            .badge {
              margin-left: 0 !important;
            }
            
            .gf-time-helper {
              margin-left: -5px;
            }
          }
        }
      }
      
      .discussion-meta > .discussion-meta-item {
        display: flex;
        align-items: center;
        gap: 5px;
        
        & > i {
          display: contents;
          .deleted-user-wrapper {
            display: contents;
          }
        }
      }
    }
  }
}
`
  }
}
